package com.canaan.business.service.bill.impl;

import cn.hutool.core.collection.CollectionUtil;
import com.canaan.business.common.enums.inOutStock.InOrderStatusEnum;
import com.canaan.business.domain.bill.ReceiveProductBill;
import com.canaan.business.domain.bill.ReceiveProductBillCheck;
import com.canaan.business.domain.bill.ReceiveProductBillDetail;
import com.canaan.business.domain.storehouse.WmsBarcodeRecord;
import com.canaan.business.domain.vo.ReceiveProductBillCheckResVo;
import com.canaan.business.mapper.bill.ReceiveProductBillCheckMapper;
import com.canaan.business.service.bill.IReceiveProductBillCheckService;
import com.canaan.business.service.bill.IReceiveProductBillDetailService;
import com.canaan.business.service.bill.IReceiveProductBillService;
import com.canaan.business.service.storehouse.IWmsBarcodeRecordService;
import com.canaan.common.exception.ServiceException;
import com.canaan.common.utils.DateUtils;
import com.canaan.common.utils.SecurityUtils;
import com.canaan.common.utils.StringUtils;
import com.canaan.common.utils.TableNoUtil;
import org.apache.commons.lang3.time.DateFormatUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 收货清单Service业务层处理
 *
 * @author ruoyi
 * @date 2023-02-10
 */
@Service
public class ReceiveProductBillCheckServiceImpl implements IReceiveProductBillCheckService {
    @Resource
    private ReceiveProductBillCheckMapper receiveProductBillCheckMapper;
    @Resource
    private IReceiveProductBillService receiveProductBillService;
    @Resource
    private IReceiveProductBillDetailService receiveProductBillDetailService;;
    @Resource
    private IWmsBarcodeRecordService wmsBatchRecordService;
    @Resource
    private IWmsBarcodeRecordService wmsBarcodeRecordService;


    /**
     * 查询收货清单
     *
     * @param id 收货清单主键
     * @return 收货清单
     */
    @Override
    public ReceiveProductBillCheck selectReceiveProductBillCheckById(Long id) {
        return receiveProductBillCheckMapper.selectReceiveProductBillCheckById(id);
    }

    /**
     * 查询收货清单列表
     *
     * @param receiveProductBillCheck 收货清单
     * @return 收货清单
     */
    @Override
    public List<ReceiveProductBillCheck> selectReceiveProductBillCheckList(ReceiveProductBillCheck receiveProductBillCheck) {
        return receiveProductBillCheckMapper.selectReceiveProductBillCheckList(receiveProductBillCheck);
    }

    /**
     * 新增收货清单
     *
     * @param receiveProductBillCheck 收货清单
     * @return 结果
     */
    @Override
    public ReceiveProductBillCheckResVo insertReceiveProductBillCheck(ReceiveProductBillCheck receiveProductBillCheck) {
        //校验有没有对应的收货单
        ReceiveProductBill bill = receiveProductBillService.selectReceiveProductBillByNo(receiveProductBillCheck.getBillNo());
        if (bill==null){
            throw new ServiceException("找不到收货单");
        }
        //校验有没有对应的到货单
        ReceiveProductBillDetail detail = new ReceiveProductBillDetail();
        detail.setBillNo(bill.getNo());
        detail.setProductNo(receiveProductBillCheck.getProductNo());
        List<ReceiveProductBillDetail> detailList = receiveProductBillDetailService.selectReceiveProductBillDetailList(detail);
        if(detailList.isEmpty()){
            throw new ServiceException("找不到对应的收货单");
        }
        //取得同物料已收货的数量
        ReceiveProductBillCheck check = new ReceiveProductBillCheck();
        check.setBillNo(bill.getNo());
        check.setProductNo(receiveProductBillCheck.getProductNo());
        List<ReceiveProductBillCheck> list = this.selectReceiveProductBillCheckList(check);
        long oldNum = list.stream().mapToLong(ReceiveProductBillCheck::getQty).sum();
        //校验数据是否有超出到货单数量
        if(detailList.get(0).getQty() < receiveProductBillCheck.getQty() + oldNum){
            throw new ServiceException("收货总数不能大于到货单数量");
        }
        //插入条码记录
        //保存数据
        if(StringUtils.isBlank(receiveProductBillCheck.getNo())){
            receiveProductBillCheck.setNo(TableNoUtil.getNo(ReceiveProductBillCheck.class));
        }
        receiveProductBillCheck.setOutBarcode(detail.getOutBarcode());
        receiveProductBillCheck.setCreateBy(SecurityUtils.getUsername());
        receiveProductBillCheck.setCreateTime(DateUtils.getNowDate());
         receiveProductBillCheckMapper.insertReceiveProductBillCheck(receiveProductBillCheck);
        //如果收货单状态为新建就变更为进行中
        if(InOrderStatusEnum.NEW.getCode().equals(bill.getStatus())){
            bill.setStatus(InOrderStatusEnum.PICKING.getCode());
            receiveProductBillService.updateReceiveProductBill(bill);
        }
        ReceiveProductBillCheckResVo vo =new ReceiveProductBillCheckResVo();
        return vo;
    }

    /**
     * 批量新增收货清单
     *
     * @param receiveProductBillCheckList 收货清单列表
     * @return 结果
     */
    @Override
    public int batchInsertReceiveProductBillCheck(List<ReceiveProductBillCheck> receiveProductBillCheckList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (ReceiveProductBillCheck receiveProductBillCheck : receiveProductBillCheckList){
            if(StringUtils.isBlank(receiveProductBillCheck.getNo())){
                receiveProductBillCheck.setNo(TableNoUtil.getNo(ReceiveProductBillCheck.class));
            }
            receiveProductBillCheck.setCreateBy(username);
            receiveProductBillCheck.setCreateTime(currerTime);
        }
        int insertNum = 0;
        for (int i=0; i<receiveProductBillCheckList.size();) {
            int endIndex = i+500;
            if (endIndex > receiveProductBillCheckList.size()) {
                endIndex = receiveProductBillCheckList.size();
            }
            insertNum = insertNum + receiveProductBillCheckMapper.batchInsertReceiveProductBillCheck(receiveProductBillCheckList.subList(i, endIndex));
            i = endIndex;
        }
        return insertNum;
    }

    /**
     * 修改收货清单
     *
     * @param receiveProductBillCheck 收货清单
     * @return 结果
     */
    @Override
    public int updateReceiveProductBillCheck(ReceiveProductBillCheck receiveProductBillCheck) {
        receiveProductBillCheck.setUpdateBy(SecurityUtils.getUsername());
        receiveProductBillCheck.setUpdateTime(DateUtils.getNowDate());
        return receiveProductBillCheckMapper.updateReceiveProductBillCheck(receiveProductBillCheck);
    }

    /**
     * 批量修改收货清单
     *
     * @param receiveProductBillCheckList 收货清单列表
     * @return 结果
     */
    @Override
    public int batchUpdateReceiveProductBillCheck(List<ReceiveProductBillCheck> receiveProductBillCheckList) {
        String username = SecurityUtils.getUsername();
        Date currerTime = DateUtils.getNowDate();
        for (ReceiveProductBillCheck receiveProductBillCheck : receiveProductBillCheckList){
            receiveProductBillCheck.setUpdateBy(username);
            receiveProductBillCheck.setUpdateTime(currerTime);
        }
        int updateNum = 0;
        for (int i=0; i<receiveProductBillCheckList.size();) {
            int endIndex = i+500;
            if (endIndex > receiveProductBillCheckList.size()) {
                endIndex = receiveProductBillCheckList.size();
            }
            updateNum = updateNum + receiveProductBillCheckMapper.batchUpdateReceiveProductBillCheck(receiveProductBillCheckList.subList(i, endIndex));
            i = endIndex;
        }
        return updateNum;
    }

    /**
     * 批量删除收货清单
     *
     * @param ids 需要删除的收货清单主键集合
     * @return 结果
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public int deleteReceiveProductBillCheckByIds(Long[] ids) {
        //获取条码
     List<ReceiveProductBillCheck> checkList = this.receiveProductBillCheckMapper.selectReceiveProductBillCheckByIds(ids);
     if(CollectionUtil.isNotEmpty(checkList)){
         List<String> barcodeList = checkList.stream().map(ReceiveProductBillCheck::getInBarcode).collect(Collectors.toList());
         if(CollectionUtil.isNotEmpty(barcodeList)){
             String[] bacodeArray =barcodeList.toArray(new String[barcodeList.size()]);
             wmsBarcodeRecordService.deleteWmsBarcodeRecordByBarcode(bacodeArray);
         }
     }
     return receiveProductBillCheckMapper.deleteReceiveProductBillCheckByIds(ids);
    }

    /**
     * 删除收货清单信息
     *
     * @param id 收货清单主键
     * @return 结果
     */
    @Override
    public int deleteReceiveProductBillCheckById(Long id) {
        return receiveProductBillCheckMapper.deleteReceiveProductBillCheckById(id);
    }

    /**
     * 查询收货清单
     *
     * @param no 编号
     * @return 收货清单
     */
    @Override
    public ReceiveProductBillCheck selectReceiveProductBillCheckByNo(String no) {
        return receiveProductBillCheckMapper.selectReceiveProductBillCheckByNo(no);
    }

    /**
     * 批量删除收货清单
     *
     * @param nos 需要删除的编号集合
     * @return 结果
     */
    @Override
    public int deleteReceiveProductBillCheckByNos(String[] nos) {
        return receiveProductBillCheckMapper.deleteReceiveProductBillCheckByNos(nos);
    }

    /**
     * 删除收货清单信息
     *
     * @param no 编号
     * @return 结果
     */
    @Override
    public int deleteReceiveProductBillCheckByNo(String no) {
        return receiveProductBillCheckMapper.deleteReceiveProductBillCheckByNo(no);
    }
}
